package es.ucm.fdi.healthpred.modelo.motor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import es.ucm.fdi.healthpred.controlador.Controlador;
import es.ucm.fdi.healthpred.controlador.excepciones.ExcepcionCapturaDatos;
import es.ucm.fdi.healthpred.controlador.excepciones.ExcepcionTransaccion;
import es.ucm.fdi.healthpred.controlador.utils.ConstantsString;
import es.ucm.fdi.healthpred.modelo.beans.CondicionesResidencia;
import es.ucm.fdi.healthpred.modelo.beans.CondicionesResidenciaId;
import es.ucm.fdi.healthpred.modelo.beans.CondicionesTrabajo;
import es.ucm.fdi.healthpred.modelo.beans.CondicionesTrabajoId;
import es.ucm.fdi.healthpred.modelo.beans.HabitosAlimenticios;
import es.ucm.fdi.healthpred.modelo.beans.HabitosAlimenticiosId;
import es.ucm.fdi.healthpred.modelo.beans.HabitosHigienicos;
import es.ucm.fdi.healthpred.modelo.beans.HabitosHigienicosId;
import es.ucm.fdi.healthpred.modelo.beans.HabitosPerjudiciales;
import es.ucm.fdi.healthpred.modelo.beans.HabitosPerjudicialesId;
import es.ucm.fdi.healthpred.modelo.beans.HechoClinico;
import es.ucm.fdi.healthpred.modelo.beans.HechosSintomas;
import es.ucm.fdi.healthpred.modelo.beans.Historial;
import es.ucm.fdi.healthpred.modelo.beans.HistorialId;
import es.ucm.fdi.healthpred.modelo.beans.Hobbie;
import es.ucm.fdi.healthpred.modelo.beans.HobbieId;
import es.ucm.fdi.healthpred.modelo.beans.Patologias;
import es.ucm.fdi.healthpred.modelo.beans.PatologiasId;
import es.ucm.fdi.healthpred.modelo.beans.PerfilClinico;
import es.ucm.fdi.healthpred.modelo.beans.PerfilPersona;
import es.ucm.fdi.healthpred.modelo.beans.Persona;
import es.ucm.fdi.healthpred.modelo.beans.Reglas;
import es.ucm.fdi.healthpred.modelo.beans.ReglasConclusiones;
import es.ucm.fdi.healthpred.modelo.beans.ReglasId;
import es.ucm.fdi.healthpred.modelo.beans.ReglasPremisas;
import es.ucm.fdi.healthpred.modelo.beans.Resultado;
import es.ucm.fdi.healthpred.modelo.beans.ResultadoId;
import es.ucm.fdi.healthpred.vista.DatosCliente;
import es.ucm.fdi.healthpred.vista.ModoBuscar;

/**
 * Establece las sesiones y transacciones necesarias para hacer consultas SQL a
 * la BD de tipo "SELECT", "INSERT", "UPDATE" y "DELETE" para distintos objetos.
 * Para ello se ayuda de las funciones que ofrece la librer&iacute;a Hibernate.
 * 
 * @since 1.0
 * 
 * @version 1.0
 * 
 * @author &Aacute;lvaro G&oacute;mez Porris
 * @author V&iacute;ctor L&oacute;pez Monte
 * @author Carlos Rodr&iacute;guez Colliga
 * 
 */
public class MotorConsulta {

	/* PUBLIC STATIC */
	/**
	 * @param dni
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public static void borrarPatologiasPrevias(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			ArrayList<Integer> codPatologias = null;
			String query = "SELECT distinct P.id.codigo FROM Patologias AS P WHERE P.id.dni = '"
					+ dni + "'";
			codPatologias = (ArrayList<Integer>) session.createQuery(query)
					.list();
			for (int i = 0; i < codPatologias.size(); i++) {
				PatologiasId pId = new PatologiasId(dni, codPatologias.get(i));
				session.delete(session.load(Patologias.class, pId));
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}

	}

	/**
	 * @param dni
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public static void borrarResultadosPrevios(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			ArrayList<Integer> codResultados = null;
			String query = "SELECT distinct R.id.codigo FROM Resultado AS R WHERE R.id.dni = '"
					+ dni + "'";
			codResultados = (ArrayList<Integer>) session.createQuery(query)
					.list();
			for (int i = 0; i < codResultados.size(); i++) {
				ResultadoId rId = new ResultadoId(dni, codResultados.get(i));
				session.delete(session.load(Resultado.class, rId));
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}

	}

	/**
	 * @param dni
	 * @throws ExcepcionTransaccion
	 */
	public static void borrarSintomasPrevios(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Set<HechosSintomas> sintomas = p.getHechosSintomases();
			sintomas.removeAll(sintomas);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param datos
	 * @throws ExcepcionTransaccion
	 */
	public static void nuevasVariables(HashMap<String, Object> datos)
			throws ExcepcionTransaccion {
		try {
			nuevoHabitoAlimenticio(Controlador.dni, 1, datos);
			nuevoHabitoHigienico(Controlador.dni, 1, datos);
			nuevoHabitoPerjudiciales(Controlador.dni, 1, datos);
			nuevoCondicionesTrabajo(Controlador.dni, 1, datos);
			nuevoCondicionesResidencia(Controlador.dni, 1, datos);
		} catch (ExcepcionTransaccion e) {
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		}
	}

	/* PRIVADOS STATIC */
	private static CondicionesResidencia estableceCondicionesResidencia(
			String dni, int inf, HashMap<String, Object> datos) {
		CondicionesResidencia condiciones = new CondicionesResidencia();
		CondicionesResidenciaId hId = new CondicionesResidenciaId();
		hId.setDni(dni);
		condiciones.setId(hId);
		condiciones.setTemperaturaMedia(Integer.valueOf(datos.get(
				ConstantsString.VARIABLESINFERENCIA.TEMPERATURA_R).toString()));
		condiciones.setHumedad(datos.get(
				ConstantsString.VARIABLESINFERENCIA.HUMEDAD_R).toString());
		condiciones.setHorasSol(Integer.valueOf(datos.get(
				ConstantsString.VARIABLESINFERENCIA.SOL_R).toString()));
		condiciones.setCalidadAire(datos.get(
				ConstantsString.VARIABLESINFERENCIA.AIRE_R).toString());
		condiciones.setContaminacionAcustica(datos.get(
				ConstantsString.VARIABLESINFERENCIA.RUIDO_R).toString());

		return condiciones;
	}

	private static CondicionesTrabajo estableceCondicionesTrabajo(String dni,
			int inf, HashMap<String, Object> datos) {
		CondicionesTrabajo condiciones = new CondicionesTrabajo();
		CondicionesTrabajoId hId = new CondicionesTrabajoId();
		hId.setDni(dni);
		condiciones.setId(hId);
		condiciones.setTemperaturaMedia(Integer.valueOf(datos.get(
				ConstantsString.VARIABLESINFERENCIA.TEMPERATURA_T).toString()));
		condiciones.setHumedad(datos.get(
				ConstantsString.VARIABLESINFERENCIA.HUMEDAD_T).toString());
		condiciones.setHorasSol(Integer.valueOf(datos.get(
				ConstantsString.VARIABLESINFERENCIA.SOL_T).toString()));
		condiciones.setCalidadAire(datos.get(
				ConstantsString.VARIABLESINFERENCIA.AIRE_T).toString());
		condiciones.setContaminacionAcustica(datos.get(
				ConstantsString.VARIABLESINFERENCIA.RUIDO_T).toString());
		condiciones.setVertidos(datos.get(
				ConstantsString.VARIABLESINFERENCIA.VERTIDOS).toString());
		condiciones.setEsfuerzoFisico(datos.get(
				ConstantsString.VARIABLESINFERENCIA.ESFUERZO).toString());

		return condiciones;
	}

	private static HabitosAlimenticios estableceHabitoAlimenticio(String dni,
			int inf, HashMap<String, Object> datos) {
		HabitosAlimenticios habito = new HabitosAlimenticios();
		HabitosAlimenticiosId hId = new HabitosAlimenticiosId();
		hId.setDni(dni);
		habito.setId(hId);
		habito.setConsumoCerealesfeculas(datos.get(
				ConstantsString.VARIABLESINFERENCIA.CEREALES).toString());
		habito.setConsumoFrutasverduras(datos.get(
				ConstantsString.VARIABLESINFERENCIA.FRUTAS).toString());
		habito.setConsumoGrasaslipidos(datos.get(
				ConstantsString.VARIABLESINFERENCIA.GRASAS).toString());
		habito.setConsumoCarne(datos.get(
				ConstantsString.VARIABLESINFERENCIA.CARNE).toString());
		habito.setConsumoPescado(datos.get(
				ConstantsString.VARIABLESINFERENCIA.PESCADO).toString());
		habito.setConsumoLacteoshuevos(datos.get(
				ConstantsString.VARIABLESINFERENCIA.LACTEOS).toString());
		habito.setConsumoAgua(datos.get(
				ConstantsString.VARIABLESINFERENCIA.AGUA).toString());
		habito.setNumComidasDia(Integer.valueOf(datos.get(
				ConstantsString.VARIABLESINFERENCIA.COMIDASDIA).toString()));

		return habito;
	}

	private static HabitosHigienicos estableceHabitoHigienico(String dni,
			int inf, HashMap<String, Object> datos) {
		HabitosHigienicos habito = new HabitosHigienicos();
		HabitosHigienicosId hId = new HabitosHigienicosId();
		hId.setDni(dni);
		habito.setId(hId);
		habito.setHigieneCorporal(datos.get(
				ConstantsString.VARIABLESINFERENCIA.CORPORAL).toString());
		habito.setHigieneBucal(datos.get(
				ConstantsString.VARIABLESINFERENCIA.BUCAL).toString());
		habito.setHigieneVestimenta(datos.get(
				ConstantsString.VARIABLESINFERENCIA.VESTIMENTA).toString());
		habito.setHigieneVivienda(datos.get(
				ConstantsString.VARIABLESINFERENCIA.VIVIENDA).toString());
		habito.setHigieneAlimentos(datos.get(
				ConstantsString.VARIABLESINFERENCIA.ALIMENTOS).toString());

		return habito;
	}

	private static HabitosPerjudiciales estableceHabitoPerjudicial(String dni,
			int inf, HashMap<String, Object> datos) {
		HabitosPerjudiciales habito = new HabitosPerjudiciales();
		HabitosPerjudicialesId hId = new HabitosPerjudicialesId();
		hId.setDni(dni);
		habito.setId(hId);
		habito.setToxicos(datos
				.get(ConstantsString.VARIABLESINFERENCIA.TOXICOS).toString());
		habito.setSedentarismo(datos.get(
				ConstantsString.VARIABLESINFERENCIA.SEDENTARISMO).toString());
		habito.setDefectosPosturales(datos.get(
				ConstantsString.VARIABLESINFERENCIA.POSTURALES).toString());
		habito.setNivelEstres(datos.get(
				ConstantsString.VARIABLESINFERENCIA.ESTRES).toString());
		habito.setHorasSuenyoDia(Integer.valueOf(datos.get(
				ConstantsString.VARIABLESINFERENCIA.SUENYO).toString()));

		return habito;
	}

	@SuppressWarnings("unchecked")
	private static boolean existeHabitoCondicion(String dni, String modo)
			throws ExcepcionTransaccion {
		boolean r;
		String query = null;
		int size = 0;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			if (modo.equals("alimentos")) {
				query = "SELECT HA FROM HabitosAlimenticios AS HA WHERE HA.id.dni = '"
						+ dni + "'";
				ArrayList<HabitosAlimenticios> l = (ArrayList<HabitosAlimenticios>) session
						.createQuery(query).list();
				size = l.size();
			} else if (modo.equals("higienicos")) {
				query = "SELECT HH FROM HabitosHigienicos AS HH WHERE HH.id.dni = '"
						+ dni + "'";
				ArrayList<HabitosHigienicos> l = (ArrayList<HabitosHigienicos>) session
						.createQuery(query).list();
				size = l.size();
			} else if (modo.equals("perjudiciales")) {
				query = "SELECT HP FROM HabitosPerjudiciales AS HP WHERE HP.id.dni = '"
						+ dni + "'";
				ArrayList<HabitosPerjudiciales> l = (ArrayList<HabitosPerjudiciales>) session
						.createQuery(query).list();
				size = l.size();
			} else if (modo.equals("residencia")) {
				query = "SELECT CR FROM CondicionesResidencia AS CR WHERE CR.id.dni = '"
						+ dni + "'";
				ArrayList<CondicionesResidencia> l = (ArrayList<CondicionesResidencia>) session
						.createQuery(query).list();
				size = l.size();
			} else if (modo.equals("trabajo")) {
				query = "SELECT CT FROM CondicionesTrabajo AS CT WHERE CT.id.dni = '"
						+ dni + "'";
				ArrayList<CondicionesTrabajo> l = (ArrayList<CondicionesTrabajo>) session
						.createQuery(query).list();
				size = l.size();
			}
			r = (size > 0);
			tx.commit();
			return r;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private static void nuevoCondicionesResidencia(String dni, int inf,
			HashMap<String, Object> datos) throws ExcepcionTransaccion {

		boolean existe = existeHabitoCondicion(dni, "residencia");

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		CondicionesResidencia hA = estableceCondicionesResidencia(dni, inf,
				datos);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			hA.setPersona(p);
			if (existe)
				session.saveOrUpdate(hA);
			else
				session.save(hA);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private static void nuevoCondicionesTrabajo(String dni, int inf,
			HashMap<String, Object> datos) throws ExcepcionTransaccion {

		boolean existe = existeHabitoCondicion(dni, "trabajo");

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		CondicionesTrabajo hA = estableceCondicionesTrabajo(dni, inf, datos);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			hA.setPersona(p);
			if (existe)
				session.saveOrUpdate(hA);
			else
				session.save(hA);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private static void nuevoHabitoAlimenticio(String dni, int inf,
			HashMap<String, Object> datos) throws ExcepcionTransaccion {

		boolean existe = existeHabitoCondicion(dni, "alimentos");

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		HabitosAlimenticios hA = estableceHabitoAlimenticio(dni, inf, datos);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			hA.setPersona(p);
			if (existe)
				session.saveOrUpdate(hA);
			else
				session.save(hA);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private static void nuevoHabitoHigienico(String dni, int inf,
			HashMap<String, Object> datos) throws ExcepcionTransaccion {

		boolean existe = existeHabitoCondicion(dni, "higienicos");

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		HabitosHigienicos hA = estableceHabitoHigienico(dni, inf, datos);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			hA.setPersona(p);
			if (existe)
				session.saveOrUpdate(hA);
			else
				session.save(hA);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private static void nuevoHabitoPerjudiciales(String dni, int inf,
			HashMap<String, Object> datos) throws ExcepcionTransaccion {

		boolean existe = existeHabitoCondicion(dni, "perjudiciales");

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		HabitosPerjudiciales hA = estableceHabitoPerjudicial(dni, inf, datos);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			hA.setPersona(p);
			if (existe)
				session.saveOrUpdate(hA);
			else
				session.save(hA);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/* PUBLIC */
	/**
	 * @param id
	 * @param nivel
	 * @throws ExcepcionTransaccion
	 */
	public void activaRegla(int id, int nivel) throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			ReglasId rId = new ReglasId(nivel, id);
			Reglas r = new Reglas(rId, "Si");
			session.update(r);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param camposBusqueda
	 * @return La lista de objetos encontrados
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Object> buscar(HashMap<String, Object> camposBusqueda)
			throws ExcepcionTransaccion {
		ArrayList<Object> listaPersonas = null;
		ModoBuscar modo = (ModoBuscar) camposBusqueda
				.get(ConstantsString.B_MODO);
		boolean buscar = false;
		boolean[] vacias = new boolean[4];
		String[] clausulas = new String[4];
		String operador = " AND ";
		String consulta = "SELECT PER FROM Persona AS PER WHERE ";
		String dni = (String) camposBusqueda.get(ConstantsString.B_DNI);
		String nombre = (String) camposBusqueda.get(ConstantsString.B_NOMBRE);
		String apellido = (String) camposBusqueda
				.get(ConstantsString.B_APELLIDO);
		String telefono = (String) camposBusqueda.get(
				ConstantsString.B_TELEFONO).toString();

		for (int i = 0; i < 4; i++) {
			vacias[i] = true;
			clausulas[i] = null;
		}

		if (modo == ModoBuscar.M_O) {
			operador = " OR ";
		}
		if (!(dni.equals(ConstantsString.VACIO))) {
			vacias[0] = false;
			clausulas[0] = "PER.dni = '" + dni + "'";
			buscar = true;
		}
		if (!(nombre.equals(ConstantsString.VACIO))) {
			vacias[1] = false;
			clausulas[1] = "PER.nombre = '" + nombre + "'";
			buscar = true;
		}
		if (!(apellido.equals(ConstantsString.VACIO))) {
			vacias[2] = false;
			clausulas[2] = "(PER.apellido1 = '" + apellido + "' OR "
					+ "PER.apellido2 = '" + apellido + "')";
			buscar = true;
		}
		if (!(telefono.equals(ConstantsString.VACIO))) {
			vacias[3] = false;
			clausulas[3] = "PER.telefono = '" + telefono + "'";
			buscar = true;
		}

		if (buscar) {
			int i = 0;
			while ((vacias[i]) && (i < 4)) {
				i++;
			}
			if (i < 4) {
				consulta += clausulas[i];
				for (int j = i + 1; j < 4; j++) {
					if (!vacias[j]) {
						consulta += operador + clausulas[j];
					}
				}
			}

			Controlador.conecta();
			Session session = Controlador.sesion;
			Transaction tx = session.getTransaction();

			try {
				tx.begin();
				listaPersonas = (ArrayList<Object>) session.createQuery(
						consulta).list();
				tx.commit();
				return listaPersonas;
			} catch (Exception e) {
				if (tx != null) {
					tx.rollback();
				}
				e.printStackTrace();
				throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
			} finally {
				Controlador.reiniciaSesion();
			}
		}
		return listaPersonas;
	}

	/**
	 * @return La lista de s&iacute;ntomas.
	 * @throws ExcepcionTransaccion
	 */
	public ArrayList<String> dameHechosSintomas() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		ArrayList<String> lista = new ArrayList<String>();
		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Set<HechosSintomas> sintomas = p.getHechosSintomases();
			Iterator<HechosSintomas> it = sintomas.iterator();
			HechosSintomas hecho;
			while (it.hasNext()) {
				hecho = (HechosSintomas) it.next();
				lista.add(hecho.getDescripcion());
			}

			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return La lista de patolog&iacute;as asociadas al dni de entrada.
	 * @throws ExcepcionTransaccion
	 */
	public ArrayList<Patologias> damePatologias() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		ArrayList<Patologias> lista = new ArrayList<Patologias>();
		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Set<Patologias> patologias = p.getPatologiases();
			Iterator<Patologias> it = patologias.iterator();
			Patologias patologia;
			while (it.hasNext()) {
				patologia = (Patologias) it.next();
				lista.add(patologia);
			}

			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @return El {@link PerfilClinico} asociado al dni de entrada.
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public PerfilClinico damePerfilClinico(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		try {
			tx.begin();
			String query = "SELECT PC FROM PerfilClinico AS PC WHERE PC.dni = '"
					+ dni + "'";
			ArrayList<PerfilClinico> l = (ArrayList<PerfilClinico>) session
					.createQuery(query).list();
			tx.commit();
			return l.get(0);
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @return El {@link PerfilPersona} asociado al dni de entrada.
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public PerfilPersona damePerfilPersona(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		try {
			tx.begin();
			String query = "SELECT PP FROM PerfilPersona AS PP WHERE PP.dni = '"
					+ dni + "'";
			ArrayList<PerfilPersona> l = (ArrayList<PerfilPersona>) session
					.createQuery(query).list();
			tx.commit();
			return l.get(0);
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	public ArrayList<Resultado> dameResultados() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		ArrayList<Resultado> lista = new ArrayList<Resultado>();
		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Set<Resultado> resultado = p.getResultados();
			Iterator<Resultado> it = resultado.iterator();
			Resultado result;
			while (it.hasNext()) {
				result = (Resultado) it.next();
				lista.add(result);
			}

			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param nivel
	 * @throws ExcepcionTransaccion
	 */
	public void desactivaReglas(int nivel) throws ExcepcionTransaccion {
		ArrayList<Reglas> lista = obtenReglasActivas(nivel);
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			for (int i = 0; i < lista.size(); i++) {
				Reglas r = lista.get(i);
				ReglasId rId = new ReglasId(nivel, r.getId().getIdRegla());
				r = new Reglas(rId, "No");
				session.update(r);
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param tabla
	 * @param att
	 * @param dni
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public Object devuelveValor(String tabla, String att, String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		String query;
		Object r = null;
		try {
			tx.begin();
			if (esMedia(att)) {
				query = "SELECT E.gravedad "
						+ "FROM HechoClinico AS E, Historial AS H "
						+ "WHERE H.id.dni = '"
						+ dni
						+ "' AND NOT H.estado = 'Solucionado' AND H.id.codigo = E.codigo "
						+ "AND NOT E.tipo = 'operacion' AND E.sistema = '"
						+ att + "'";
				ArrayList<String> lista = (ArrayList<String>) session
						.createQuery(query).list();
				r = dameMedia(lista);
			} else if (att.equals("codigo") && tabla.equals("Sintomas")) {
				Persona p = (Persona) session.load(Persona.class, dni);
				Set<HechosSintomas> sintomas = p.getHechosSintomases();
				Iterator<HechosSintomas> it = sintomas.iterator();
				HechosSintomas hecho;
				ArrayList<Integer> lista = new ArrayList<Integer>();
				while (it.hasNext()) {
					hecho = (HechosSintomas) it.next();
					lista.add(hecho.getCodigo());
				}
				r = lista;
			} else if (att.equals("codigo") && tabla.equals("Patologias")) {
				query = "SELECT P.id." + att + " FROM " + tabla
						+ " AS P WHERE P.id.dni = '" + dni
						+ "' AND NOT P.estado = 'Solucionado'";
				Query q = session.createQuery(query);
				r = q.list();
			} else {
				if (tabla.equals("Hobbie")
						|| tabla.equals("CondicionesResidencia")
						|| tabla.equals("CondicionesTrabajo")// CLAVE COMPUESTA
						|| tabla.equals("HabitosAlimenticios")
						|| tabla.equals("HabitosHigienicos")
						|| tabla.equals("HabitosPerjudiciales")
						|| tabla.equals("Historial"))
					query = "SELECT P." + att + " FROM " + tabla
							+ " AS P WHERE P.id.dni = '" + dni + "'";
				else
					query = "SELECT P." + att + " FROM " + tabla
							+ " AS P WHERE P.dni = '" + dni + "'";
				Query q = session.createQuery(query);
				r = q.list();
			}

			tx.commit();
			return r;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param datosCliente
	 * @throws ExcepcionCapturaDatos
	 * @throws ExcepcionTransaccion
	 */
	public void editarCliente(DatosCliente datosCliente)
			throws ExcepcionCapturaDatos, ExcepcionTransaccion {

		Persona persona = datosCliente.getPersona();

		for (int i = 0; i < Controlador.historiasDelete.size(); i++) {
			int codigo = Controlador.historiasDelete.get(i);
			HistorialId id = new HistorialId(Controlador.dni, codigo);
			eliminarHistoria(id);
		}

		for (int i = 0; i < Controlador.hobbiesDelete.size(); i++) {
			String nombre = Controlador.hobbiesDelete.get(i);
			HobbieId id = new HobbieId(Controlador.dni, nombre);
			eliminarHobbie(id);
		}

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			if (persona.getDni().equalsIgnoreCase(Controlador.dni)) {
				session.update(persona);
				session.update(persona.getResidencia());
				session.update(persona.getDatosSociales());
				session.update(persona.getEstudios());
				session.update(persona.getDatosProfesionales());
				tx.commit();

				for (int i = 0; i < datosCliente.getHobbies().size(); i++) {
					editarHobbie((Hobbie) datosCliente.getHobbies().get(i));
				}

				for (int i = 0; i < datosCliente.getHistorial().size(); i++) {
					editarHistoria((Historial) datosCliente.getHistorial().get(
							i));
				}
			} else {
				String clave = new String(Controlador.dni);
				session.delete(session.load(Persona.class, clave));
				session.save(persona);
				session.save(persona.getResidencia());
				session.save(persona.getDatosSociales());
				session.save(persona.getEstudios());
				session.save(persona.getDatosProfesionales());
				tx.commit();

				for (int i = 0; i < datosCliente.getHobbies().size(); i++) {
					nuevoHobbie((Hobbie) datosCliente.getHobbies().get(i));
				}

				for (int i = 0; i < datosCliente.getHistorial().size(); i++) {
					nuevaHistoria((Historial) datosCliente.getHistorial()
							.get(i));
				}
			}
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @throws ExcepcionTransaccion
	 */
	public void eliminarCliente() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			session.delete(session.load(Persona.class, Controlador.dni));
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param id
	 * @throws ExcepcionTransaccion
	 */
	public void eliminarHistoria(HistorialId id) throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			session.delete(session.load(Historial.class, id));
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param id
	 * @throws ExcepcionTransaccion
	 */
	public void eliminarHobbie(HobbieId id) throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			session.delete(session.load(Hobbie.class, id));
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}

	}

	/**
	 * @param att
	 * @return
	 */
	public boolean esCategoriaPersona(String att) {
		return (att.equals("categoriaCultural")
				|| att.equals("categoriaEconomica")
				|| att.equals("categoriaProfesional") || att
					.equals("categoriaSocial"));
	}

	/**
	 * @param att
	 * @return
	 */
	public boolean esMedia(String att) {
		return (att.equals("Muscular") || att.equals("Oseo")
				|| att.equals("Articular") || att.equals("Nervioso")
				|| att.equals("Digestivo") || att.equals("Excretor")
				|| att.equals("Inmunitario") || att.equals("Tegumentario")
				|| att.equals("Reproductor") || att.equals("Respiratorio")
				|| att.equals("Cardiovascular") || att.equals("Linfatico") || att
					.equals("Mental"));
	}

	/**
	 * @param att
	 * @return
	 */
	public boolean esNumero(String att) {
		return (att.equals("costeMes") || att.equals("numHijos")
				|| att.equals("numHijosMenores")
				|| att.equals("anyosTrabajados") || att.equals("finEstudios")
				|| att.equals("fecha") || att.equals("horasSuenyoDia")
				|| att.equals("horasSol") || att.equals("temperaturaMedia")
				|| att.equals("codigo") || att.equals("numComidasDia"));
	}

	/**
	 * @param att
	 * @return
	 */
	public boolean esReglaNivel2(String att) {
		return (att.equals("calidadAire")
				|| att.equals("contaminacionAcustica") || att.equals("humedad")
				|| att.equals("consumoCerealesfeculas")
				|| att.equals("consumoFrutasverduras")
				|| att.equals("consumoGrasaslipidos")
				|| att.equals("consumoCarne") || att.equals("consumoPescado")
				|| att.equals("consumoLacteoshuevos")
				|| att.equals("consumoAgua") || att.equals("higieneCorporal")
				|| att.equals("higieneBucal")
				|| att.equals("higieneVestimenta")
				|| att.equals("higieneAlimentos")
				|| att.equals("higieneVivienda") || att.equals("nivelEstres"));
	}

	/**
	 * @param att
	 * @return
	 */
	public boolean esSiNo(String att) {
		return (att.equals("sedentarismo") || att.equals("defectosPosturales")
				|| att.equals("vertidos") || att.equals("esfuerzoFisico")
				|| att.equals("Digestivo") || att.equals("emancipado"));
	}

	/**
	 * @param att
	 * @return
	 */
	public boolean esSistemaNivel2(String att) {
		return (att.equals("sistemaMuscular") || att.equals("sistemaOseo")
				|| att.equals("sistemaArticular")
				|| att.equals("sistemaNervioso")
				|| att.equals("sistemaDigestivo")
				|| att.equals("sistemaExcretor")
				|| att.equals("sistemaInmunitario")
				|| att.equals("sistemaTegumentario")
				|| att.equals("sistemaReproductor")
				|| att.equals("sistemaRespiratorio")
				|| att.equals("sistemaCardiovascular")
				|| att.equals("sistemaLinfatico") || att.equals("estadoMental"));
	}

	/**
	 * @param historia
	 * @throws ExcepcionCapturaDatos
	 * @throws ExcepcionTransaccion
	 */
	public void nuevaHistoria(Historial historia) throws ExcepcionCapturaDatos,
			ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, historia.getId()
					.getDni());
			HechoClinico hecho = (HechoClinico) session.load(
					HechoClinico.class, historia.getId().getCodigo());
			historia.setPersona(p);
			historia.setHechoClinico(hecho);
			session.save(historia);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @param codigo
	 * @param estado
	 * @param coste
	 * @throws ExcepcionTransaccion
	 */
	public void nuevaPatologia(String dni, int codigo, String estado, int coste)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Patologias pat = new Patologias();
			PatologiasId pId = new PatologiasId(dni, codigo);
			pat.setId(pId);
			pat.setEstado(estado);
			pat.setCosteTratamiento(coste);
			pat.setPersona(p);
			session.saveOrUpdate(pat);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param datosCliente
	 * @throws ExcepcionCapturaDatos
	 * @throws ExcepcionTransaccion
	 */
	public void nuevoCliente(DatosCliente datosCliente)
			throws ExcepcionCapturaDatos, ExcepcionTransaccion {

		Persona persona = datosCliente.getPersona();

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			session.save(persona);
			session.save(persona.getResidencia());
			session.save(persona.getDatosSociales());
			session.save(persona.getEstudios());
			session.save(persona.getDatosProfesionales());
			tx.commit();

			for (int i = 0; i < datosCliente.getHobbies().size(); i++) {
				nuevoHobbie((Hobbie) datosCliente.getHobbies().get(i));
			}

			for (int i = 0; i < datosCliente.getHistorial().size(); i++) {
				nuevaHistoria((Historial) datosCliente.getHistorial().get(i));
			}
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param hobbie
	 * @throws ExcepcionCapturaDatos
	 * @throws ExcepcionTransaccion
	 */
	public void nuevoHobbie(Hobbie hobbie) throws ExcepcionCapturaDatos,
			ExcepcionTransaccion {

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, hobbie.getId()
					.getDni());
			hobbie.setPersona(p);
			session.save(hobbie);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @param categorias
	 * @throws ExcepcionTransaccion
	 */
	public void nuevoPerfilClinico(String dni, String[] categorias)
			throws ExcepcionTransaccion {
		boolean existePrevia = existePerfilClinico(dni);
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		PerfilClinico pC = establecePerfilClinico(dni, categorias);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			pC.setPersona(p);
			if (existePrevia)
				session.saveOrUpdate(pC);
			else
				session.save(pC);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @param categorias
	 * @throws ExcepcionTransaccion
	 */
	public void nuevoPerfilPersona(String dni, String[] categorias)
			throws ExcepcionTransaccion {
		boolean existePrevia = existePerfilPersona(dni);
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		PerfilPersona pP = establecePerfilPersona(dni, categorias);

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);// Controlador.dni
			pP.setPersona(p);
			if (existePrevia)
				session.saveOrUpdate(pP);
			else
				session.save(pP);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @param codigo
	 * @param conclusion
	 * @param tiempo
	 * @param porcentaje
	 * @throws ExcepcionTransaccion
	 */
	public void nuevoResultado(String dni, int codigo, String conclusion,
			String tiempo, int porcentaje) throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Resultado res = new Resultado();
			ResultadoId rId = new ResultadoId(dni, codigo);
			res.setId(rId);
			res.setConclusion(conclusion);
			res.setTiempoMeses(tiempo);
			res.setPorcentaje(porcentaje);
			res.setPersona(p);
			session.saveOrUpdate(res);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @param codigo
	 * @throws ExcepcionTransaccion
	 */
	public void nuevoSintoma(String dni, int codigo)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			HechosSintomas h = (HechosSintomas) session.load(
					HechosSintomas.class, codigo);
			Set<HechosSintomas> nuevo = p.getHechosSintomases();
			nuevo.add(h);
			p.setHechosSintomases(nuevo);
			session.saveOrUpdate(p);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public int obtenCodigoHecho(String tipo, String sistema, String descripcion)
			throws ExcepcionTransaccion {
		String consulta = "SELECT HC FROM HechoClinico AS HC WHERE HC.tipo = '"
				+ tipo + "' AND HC.sistema = '" + sistema
				+ "' AND HC.descripcion = '" + descripcion + "'";

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		List<HechoClinico> hecho = null;

		try {
			tx.begin();
			hecho = (List<HechoClinico>) session.createQuery(consulta).list();
			tx.commit();
			return hecho.get(0).getCodigo();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param nivel
	 * @param id
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<ReglasConclusiones> obtenConclusion(int nivel, int id)
			throws ExcepcionTransaccion {
		String query = "SELECT RC FROM ReglasConclusiones AS RC WHERE RC.id.nivel ="
				+ Integer.toString(nivel)
				+ " AND RC.id.idRegla ="
				+ Integer.toString(id);

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		ArrayList<ReglasConclusiones> lista = null;

		try {
			tx.begin();
			lista = (ArrayList<ReglasConclusiones>) session.createQuery(query)
					.list();
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	public HechoClinico obtenHecho(int codigo) throws ExcepcionTransaccion {
		HechoClinico h;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			h = (HechoClinico) session.load(HechoClinico.class, codigo);
			tx.commit();
			Controlador.reiniciaSesion();
			return h;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param tipo
	 * @param sistema
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public List<HechoClinico> obtenHechos(String tipo, String sistema)
			throws ExcepcionTransaccion {
		String query = "SELECT HC FROM HechoClinico AS HC WHERE HC.tipo = '"
				+ tipo + "' AND HC.sistema = '" + sistema + "'";
		List<HechoClinico> lista = null;

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			lista = (List<HechoClinico>) session.createQuery(query).list();
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	public ArrayList<String> obtenHechosSintomas(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		ArrayList<String> lista = new ArrayList<String>();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Set<HechosSintomas> sintomas = p.getHechosSintomases();
			Iterator<HechosSintomas> it = sintomas.iterator();
			HechosSintomas hecho;
			while (it.hasNext()) {
				hecho = (HechosSintomas) it.next();
				lista.add(hecho.getDescripcion());
			}

			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param id
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	public Historial obtenHistoria(HistorialId id) throws ExcepcionTransaccion {
		Historial h;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			h = (Historial) session.load(Historial.class, id);
			tx.commit();
			Controlador.reiniciaSesion();
			return h;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param id
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	public Hobbie obtenHobbie(HobbieId id) throws ExcepcionTransaccion {
		Hobbie h;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			h = (Hobbie) session.load(Hobbie.class, id);
			tx.commit();
			Controlador.reiniciaSesion();
			return h;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	public ArrayList<Patologias> obtenPatologias(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		ArrayList<Patologias> lista = new ArrayList<Patologias>();
		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			Set<Patologias> patologias = p.getPatologiases();
			Iterator<Patologias> it = patologias.iterator();
			Patologias patologia;
			while (it.hasNext()) {
				patologia = (Patologias) it.next();
				lista.add(patologia);
			}
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public PerfilClinico obtenPerfilClinico(String dni)
			throws ExcepcionTransaccion {
		String query = "SELECT PC FROM PerfilClinico AS PC WHERE PC.dni = '"
				+ dni + "'";
		ArrayList<PerfilClinico> l = null;

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			l = (ArrayList<PerfilClinico>) session.createQuery(query).list();
			tx.commit();
			return l.get(0);
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param dni
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public PerfilPersona obtenPerfilPersona(String dni)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			String query = "SELECT PP FROM PerfilPersona AS PP WHERE PP.dni = '"
					+ dni + "'";
			ArrayList<PerfilPersona> l = (ArrayList<PerfilPersona>) session
					.createQuery(query).list();
			tx.commit();
			Controlador.reiniciaSesion();
			return l.get(0);
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @throws ExcepcionTransaccion
	 */
	public Persona obtenPersona() throws ExcepcionTransaccion {
		Persona p;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			p = (Persona) session.load(Persona.class, Controlador.dni);
			tx.commit();
			Controlador.reiniciaSesion();
			return p;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @param nivel
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Reglas> obtenReglasActivas(int nivel)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			String query = "SELECT R FROM Reglas AS R WHERE R.id.nivel = "
					+ Integer.toString(nivel) + " AND R.activa = 'Si'";
			ArrayList<Reglas> lista = (ArrayList<Reglas>) session.createQuery(
					query).list();
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<ReglasPremisas> obtenReglasPremisas(int nivel)
			throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		try {
			tx.begin();
			String query = "SELECT RP FROM ReglasPremisas AS RP WHERE RP.id.nivel = "
					+ Integer.toString(nivel);
			ArrayList<ReglasPremisas> lista = (ArrayList<ReglasPremisas>) session
					.createQuery(query).list();
			tx.commit();
			Controlador.reiniciaSesion();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Object> obtenTodosClientes() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			ArrayList<Object> lista = (ArrayList<Object>) session.createQuery(
					"FROM Persona").list();
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Object> obtenTodasHistorias() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			ArrayList<Object> lista = (ArrayList<Object>) session.createQuery(
					"FROM Historial WHERE dni='" + Controlador.dni + "'")
					.list();
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/**
	 * @return
	 * @throws ExcepcionTransaccion
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Object> obtenTodosHobbies() throws ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			ArrayList<Object> lista = (ArrayList<Object>) session.createQuery(
					"FROM Hobbie WHERE dni='" + Controlador.dni + "'").list();
			tx.commit();
			return lista;
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	/* PRIVADOS */
	private String dameMedia(ArrayList<String> lista) {
		int valor = 0;
		for (int i = 0; i < lista.size(); i++) {
			if (lista.get(i).equals("Leve")) {
				valor = valor + 2;
			} else if (lista.get(i).equals("Moderado")) {
				valor = valor + 6;
			} else if (lista.get(i).equals("Grave")) {
				valor = valor + 12;
			} else if (lista.get(i).equals("Critico")) {
				return "Critico";
			}
		}
		if (valor == 0)
			return "Sano";
		if ((valor > 0) && (valor <= 5))
			return "Leve";
		if ((valor > 5) && (valor <= 11))
			return "Moderado";
		if ((valor > 11) && (valor <= 23))
			return "Grave";
		if (valor > 23)
			return "Critico";
		return "Sano";
	}

	private void editarHistoria(Historial historia)
			throws ExcepcionCapturaDatos, ExcepcionTransaccion {
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			HechoClinico hecho = (HechoClinico) session.load(
					HechoClinico.class, historia.getId().getCodigo());
			historia.setPersona(p);
			historia.setHechoClinico(hecho);
			session.saveOrUpdate(historia);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
			throw new ExcepcionTransaccion(ConstantsString.ERROR_TX);
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private void editarHobbie(Hobbie hobbie) throws ExcepcionCapturaDatos,
			ExcepcionTransaccion {

		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();

		try {
			tx.begin();
			Persona p = (Persona) session.load(Persona.class, Controlador.dni);
			hobbie.setPersona(p);
			session.saveOrUpdate(hobbie);
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			e.printStackTrace();
		} finally {
			Controlador.reiniciaSesion();
		}
	}

	private PerfilClinico establecePerfilClinico(String dni, String[] sistemas) {
		PerfilClinico p = new PerfilClinico();
		p.setDni(dni);
		p.setSistemaMuscular(sistemas[0]);
		p.setSistemaOseo(sistemas[1]);
		p.setSistemaArticular(sistemas[2]);
		p.setSistemaNervioso(sistemas[3]);
		p.setSistemaDigestivo(sistemas[4]);
		p.setSistemaExcretor(sistemas[5]);
		p.setSistemaInmunitario(sistemas[6]);
		p.setSistemaTegumentario(sistemas[7]);
		p.setSistemaReproductor(sistemas[8]);
		p.setSistemaRespiratorio(sistemas[9]);
		p.setSistemaCardiovascular(sistemas[10]);
		p.setSistemaLinfatico(sistemas[11]);
		p.setEstadoMental(sistemas[12]);
		return p;
	}

	private PerfilPersona establecePerfilPersona(String dni, String[] categorias) {
		PerfilPersona p = new PerfilPersona();
		p.setDni(dni);
		p.setCategoriaCultural(categorias[0]);
		p.setCategoriaEconomica(categorias[1]);
		p.setCategoriaProfesional(categorias[2]);
		p.setCategoriaSocial(categorias[3]);
		return p;
	}

	@SuppressWarnings("unchecked")
	private boolean existePerfilClinico(String dni) {
		boolean r;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		tx.begin();
		String query = "SELECT PC FROM PerfilClinico AS PC WHERE PC.dni = '"
				+ dni + "'";
		ArrayList<PerfilClinico> l = (ArrayList<PerfilClinico>) session
				.createQuery(query).list();
		if (l.size() > 0)
			r = true;
		else
			r = false;
		tx.commit();
		Controlador.reiniciaSesion();
		return r;
	}

	@SuppressWarnings("unchecked")
	private boolean existePerfilPersona(String dni) {
		boolean r;
		Controlador.conecta();
		Session session = Controlador.sesion;
		Transaction tx = session.getTransaction();
		tx.begin();
		String query = "SELECT PP FROM PerfilPersona AS PP WHERE PP.dni = '"
				+ dni + "'";
		ArrayList<PerfilPersona> l = (ArrayList<PerfilPersona>) session
				.createQuery(query).list();
		if (l.size() > 0)
			r = true;
		else
			r = false;
		tx.commit();
		Controlador.reiniciaSesion();
		return r;
	}
}
